package com.service.lotterySystem.service.impl;

import com.service.config.utils.DateUtils;
import com.service.config.utils.IdUtil;
import com.service.config.utils.ModelMapperUtil;
import com.service.config.utils.Result;
import com.service.lotterySystem.bean.EndActivityTaskBean;
import com.service.lotterySystem.bean.StartActivityTaskBean;
import com.service.lotterySystem.dao.ActivityInfoDao;
import com.service.lotterySystem.dao.ReceiveAddressDao;
import com.service.lotterySystem.dao.UserInfoDao;
import com.service.lotterySystem.dto.AddActivityDto;
import com.service.lotterySystem.dto.QueryActivityInfoDto;
import com.service.lotterySystem.entity.ActivityInfo;
import com.service.lotterySystem.entity.ReceiveAddress;
import com.service.lotterySystem.entity.UserInfo;
import com.service.lotterySystem.rabbitmq.MsgProducer;
import com.service.lotterySystem.service.ActivityService;
import com.service.lotterySystem.service.PrizeService;
import com.service.lotterySystem.service.VFilePhysicsInfoService;
import com.service.lotterySystem.util.CronUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.service.config.constant.Constant.DATA_FORMAT_WRONG;
import static com.service.config.constant.Constant.PARAMETER_NOT_FOUND;

/**
 * @author ：hjl
 * @date ：Created in 2022/01/10 19:54
 * @description：
 */
@Service
@Slf4j
public class ActivityServiceImpl implements ActivityService {
    @Resource
    private ActivityInfoDao activityDao;
    @Resource
    private VFilePhysicsInfoService vFilePhysicsInfoService;
    @Resource
    private UserInfoDao userInfoDao;
    @Resource
    private ReceiveAddressDao receiveAddressDao;
    @Resource
    private PrizeService prizeService;

    private final Integer PAGE_SIZE = 10;
    private int beanIndex=0;
    @Resource
    private MsgProducer msgProducer;

    @Value("${spring.fileUrl}")
    String fileUrl;
    @Value("${spring.filePath}")
    String filePath;

    /**
     * 新建活动
     * @param activityDto
     * @return
     */
    @Override
    @Transactional
    public Result addActivity(AddActivityDto activityDto) {
        if (activityDto.getaBeginTime() == null || activityDto.getaEndTime() == null)
        {
            return Result.failure(DATA_FORMAT_WRONG,"当前活动未设置起始时间");
        }
        String id = IdUtil.getStringId();

        try {
            ActivityInfo activityInfo = ModelMapperUtil.strictMap(activityDto, ActivityInfo.class);
            activityInfo.setId(id);
            activityInfo.setPublishTime(DateUtils.getNowDate());
            activityInfo.setIsSend(false);
            activityInfo.setAStatus(false);
            activityInfo.setIsCalculation(0);
            if (activityDto.getaBeginTime().getTime()>System.currentTimeMillis())
            {
                //预热活动
                activityInfo.setAType(2);
            }else if (activityDto.getaEndTime().getTime()<System.currentTimeMillis())
            {
                //历史活动
                activityInfo.setAType(0);
            }else if (activityDto.getaBeginTime().getTime()<=System.currentTimeMillis() && activityDto.getaEndTime().getTime()>=System.currentTimeMillis()){
                //正在进行的活动
                activityInfo.setAType(1);
            }

            activityDao.insert(activityInfo);

            Scheduler scheduler = null;

            scheduler = StdSchedulerFactory.getDefaultScheduler();
            scheduler.start();
            JobDataMap jobDataMap;
            //活动开始时间是未来时间
            if (activityInfo.getAType()==2)
            {
                jobDataMap=new JobDataMap();
                jobDataMap.put("activityId",id);
                jobDataMap.put("taskName","startActivity_"+beanIndex);
                jobDataMap.put("groupName","addActivity");
                //开启活动定时任务
                scheduler.scheduleJob(
                        JobBuilder.newJob(StartActivityTaskBean.class).withIdentity("startActivity_"+beanIndex,"addActivity").setJobData(jobDataMap).build(),
                        TriggerBuilder.newTrigger().
                                withIdentity("startActivity_"+beanIndex,"addActivity").
                                withSchedule(CronScheduleBuilder.cronSchedule(CronUtil.getCron(activityInfo.getABeginTime()))).
                                build()
                );
            }
            //活动结束时间是未来时间
            if (activityInfo.getAType()==1 || activityInfo.getAType() == 2)
            {
                jobDataMap=new JobDataMap();
                jobDataMap.put("activityId",id);
                jobDataMap.put("taskName","endActivity_"+beanIndex);
                jobDataMap.put("groupName","addActivity");
                //结束活动定时任务
                scheduler.scheduleJob(
                        JobBuilder.newJob(EndActivityTaskBean.class).withIdentity("endActivity_"+beanIndex,"addActivity").setJobData(jobDataMap).build(),
                        TriggerBuilder.newTrigger().
                                withIdentity("endActivity_"+beanIndex,"addActivity").
                                withSchedule(CronScheduleBuilder.cronSchedule(CronUtil.getCron(activityInfo.getAEndTime()))).
                                build()
                );
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            beanIndex++;
        }

        return Result.ok().setData(id);
    }

    @Override
    public Result queryByType(Integer type) {
//        Map<String,Object> map=new HashMap<>();
//        PageHelper.startPage(page,PAGE_SIZE,"a_weight DESC");
        List<ActivityInfo> activityInfos = activityDao.queryByType(type);
//        PageInfo<ActivityInfo> pageInfo = new PageInfo(activityInfos);
        if (null == activityInfos || activityInfos.size()<=0)
        {
            return Result.failure(PARAMETER_NOT_FOUND,"当前无活动");
        }
        List<QueryActivityInfoDto> activityDtos = ModelMapperUtil.strictMapList(activityInfos, QueryActivityInfoDto.class);
//        map.put("activityDtos",activityDtos);
//        map.put("pageSize",PAGE_SIZE);
//        map.put("pageIndex",page);
//        map.put("totalRecords",pageInfo.getTotal());
//        map.put("totalPages",pageInfo.getPages());
        return Result.ok().setData(activityDtos);
    }

    @Override
    public QueryActivityInfoDto queryById(String activityId) {
        ActivityInfo activityInfo = activityDao.queryById(activityId);
        return activityInfo==null? null:ModelMapperUtil.strictMap(activityInfo,QueryActivityInfoDto.class);
    }

    /**
     * 修改活动信息，如果活动闭环，讲活动下所有中奖用户的中奖状态设置为true
     * @param activityDto
     */
    @Override
    public void updateById(QueryActivityInfoDto activityDto) {
        ActivityInfo activityInfo = ModelMapperUtil.strictMap(activityDto, ActivityInfo.class);

        if (activityInfo.getAStatus())
        {
            //活动正式闭环
            //查询活动下所有的中奖用户
            List<UserInfo> userInfos = ModelMapperUtil.strictMapList(prizeService.queryPrizedUser(activityDto.getId()).getData(),UserInfo.class);
            //将中奖用户的中奖状态设置为true
            userInfos.forEach(userInfo -> userInfo.setUStatus(true));
            userInfoDao.insertOrUpdateBatch(userInfos);
        }

        activityDao.update(activityInfo);
    }

    @Override
    public Result deleteById(String activityId) {
        activityDao.deleteById(activityId);
        return Result.ok();
    }

    @Override
    public Result uploadImage(String aId, MultipartFile file, Integer isType) {
        try {
            return vFilePhysicsInfoService.uploadServiceLogo(file, aId, isType);
        } catch (Exception e) {
            e.printStackTrace();
            return Result.ok();
        }
    }

    /**
     * 查询用户参加的所有活动
     * @param uid
     * @return
     */
    @Override
    public List<QueryActivityInfoDto> queryActivitiesByUid(String uid)
    {
        List<QueryActivityInfoDto> activityDtos=new ArrayList<>();
        List<ActivityInfo> activityInfos = activityDao.queryActivitiesByUid(uid);
        if (null!=activityInfos && activityInfos.size()>0)
        {
            activityDtos = ModelMapperUtil.strictMapList(activityInfos, QueryActivityInfoDto.class);
        }


        return activityDtos;
    }

    /**
     * 开启一个活动
     * @param aid
     */
    @Override
    public void startActivity(String aid)
    {
        activityDao.startActivity(aid);
    }

    /**
     * 结束一个活动
     * @param aid
     */
    @Override
    public void endActivity(String aid)
    {
        activityDao.endActivity(aid);
    }

    @Override
    public Result queryUserAddress(String aId,String uId) {
        ActivityInfo activityInfo = activityDao.queryById(aId);
        if (null == activityInfo)
        {
            return Result.failure(PARAMETER_NOT_FOUND,"当前活动未结束或不存在");
        }
        if (activityInfo.getAType() == 1 || activityInfo.getAType() == 2)
        {
            return  Result.failure(PARAMETER_NOT_FOUND,"当前活动未结束或不存在");
        }
        if (activityInfo.getAStatus())
        {
            //活动尚未闭环
            return Result.failure(PARAMETER_NOT_FOUND,"活动尚未闭环,不能查询中奖号码");
        }
        if (activityInfo.getIsCalculation() == 1 || activityInfo.getIsCalculation() == 0 ) {
            //活动尚未闭环
            return Result.failure(PARAMETER_NOT_FOUND,"该活动的中奖名单还未开始或计算中,请耐心等待");
        }
        ReceiveAddress receiveAddress = new ReceiveAddress();
        receiveAddress.setUId(uId);
        List<ReceiveAddress>  addressList = receiveAddressDao.queryAll(receiveAddress);
        if (addressList.size() > 0) {
            List<ReceiveAddress> collect = addressList.stream().filter(ReceiveAddress::getRType).collect(Collectors.toList());
            ReceiveAddress receiveAddress1 = collect.stream().findFirst().get();
            return Result.ok().setData(receiveAddress1);
        }
        return Result.failure(PARAMETER_NOT_FOUND,"还没有填写收货地址,是否发送短信");
    }

    @Override
    public Result sendSms(String aId, String uId) {
        msgProducer.sendSms(uId,aId,0);
        return Result.ok();
    }

    public String uploadFile(MultipartFile[] files)
    {
        String accessoryUrl = "";
        List<String> list = new ArrayList<>();
        File file1;

        for (MultipartFile file : files) {
            accessoryUrl = filePath +"/"+ file.getOriginalFilename().replaceAll(" ","");
            try{
                file1 = createFile(accessoryUrl);
                file.transferTo(file1);
                //持久化附件路径
                list.add(file.getOriginalFilename());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        String s = list.toString().substring(1).substring(0, list.toString().length() - 2).replaceAll(" ","");
        return s;
    }

    /**
     * 上传文件
     * @param s
     * @return
     */
    private File createFile(String s) {
        File file = new File(s);
        return file;
    }
}
